from django.conf import settings
from django.shortcuts import render, redirect
from django.views import View
from django import http
from django.contrib.auth import login
from QQLoginTool.QQtool import OAuthQQ
from django_redis import get_redis_connection

from meiduo_mall.utils.response_code import RETCODE
from users.models import User
from .models import OAuthQQUser
import re
from .utils import generate_open_id_signature, check_open_id
from carts.utils import merge_cart_cookie_to_redis


class QQAuthURLView(View):
    # qq登录url的拼接
    def get(self, request):
        # 1.接收查询参数
        next = request.GET.get('next') or '/'

        #2.创建oAuthQQ 对象
        # auth_tool = OAuthQQ(client_id='appid',client_secret='appkey', redirect_uri='回调地址',state='')
        auth_tool = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=next)

        # 3. 获取QQ登录页面网址
        login_url = auth_tool.get_qq_url()

        # 4.响应json
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})


class QQAuthView(View):
    """QQ登录成功回调处理"""
    def get(self, request):

        # 获取查询参数中的code
        code = request.GET.get('code')
        # 校验code参数, 使用get方法可能查不到, 查不到会返回None
        if code is None:
            return http.HttpResponseForbidden('缺少code参数')
        # 创建QQ登录工具对象
        auth_tool = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                            client_secret=settings.QQ_CLIENT_SECRET,
                            redirect_uri=settings.QQ_REDIRECT_URI,)
                            # state=next)   # state用不到, 切next是关键字, 所以删掉state
        # 调用get_access_token
        access_token = auth_tool.get_access_token(code)
        # 调用get_openid
        openid = auth_tool.get_open_id(access_token)
        # 查询openid 是否和美多中的user有关联
        # 如果有关联, 关联, 如果没有关联, 做出一个绑定界面
        try:  # 用get方法查
            # 查询openid是否和美多中的user有关联
            oauth_model = OAuthQQUser.objects.get(openid=openid)

            user = oauth_model.user
            # 状态保持
            login(request, user)
            # 向cookie中存储username
            response = redirect(request.GET.get('state') or '/')
            response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)
            merge_cart_cookie_to_redis(request, response)
            return response

        except OAuthQQUser.DoesNotExist:
            context = {'openid': openid}
            return render(request, 'oauth_callback.html', context)

    def post(self, request):
        # 绑定
        query_dict = request.POST
        mobile = query_dict.get('mobile')
        password = query_dict.get('password')
        sms_code = query_dict.get('sms_code')  # 前端来的验证码
        openid = query_dict.get('openid')

        if all([mobile, password, sms_code, openid]) is False:
            return http.HttpResponseForbidden('缺少必传参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('手机号格式有误')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20个字符的密码')

        redis_conn = get_redis_connection('verify_codes')
        sms_code_server = redis_conn.get('sms_%s' % mobile)  # 服务器中的验证码
        redis_conn.delete('sms_%s' % mobile)

        if sms_code_server is None:
            return http.HttpResponseForbidden('验证码已过期')
        if sms_code_server.decode() != sms_code:
            return http.HttpResponseForbidden('验证码填写错误')

        try:
            # 查询有么有这个手机号的用户, 有就绑定, 没有就创建
            user = User.objects.get(mobile=mobile)  # 查不到就进except

            if user.check_password(password) is False:
                return http.HttpResponseForbidden('绑定失败')
        except User.DoesNotExist:

            user = User.objects.create_user(username=mobile,
                                            password=password,
                                            mobile=mobile)

        # 对openid进行解密, 绑定原始openid
        openid = check_open_id(openid)
        if openid is None:
            return http.HttpResponseForbidden('openid无效')

        OAuthQQUser.objects.create(
            openid=openid,
            user=user
        )

        login(request, user)

        # 将username存储到cookie中
        response = redirect(request.GET.get('state') or '/')
        response.set_cookie('username', user.username, max_age=settings.SESSION_COOKIE_AGE)
        merge_cart_cookie_to_redis(request, response)
        return response
